#include "buffer.h"

#define LOG_TAG "[BUFFER]"
#include "log.h"
void RingBuffer_Init(RingBuffer_t* rb, uint8_t* buffer, uint16_t capacity) {
    rb->buffer = buffer;
    rb->capacity = capacity;
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
}

void RingBuffer_Clear(RingBuffer_t* rb) {
    rb->head = rb->tail = rb->count = 0;
}

uint8_t RingBuffer_IsEmpty(const RingBuffer_t* rb) {
    return (rb->count == 0);
}

uint8_t RingBuffer_IsFull(const RingBuffer_t* rb) {
    return (rb->count >= rb->capacity);
}

uint16_t RingBuffer_Count(const RingBuffer_t* rb) {
    return rb->count;
}

uint8_t RingBuffer_WriteByte(RingBuffer_t* rb, uint8_t data) {
    if (RingBuffer_IsFull(rb)) return 0;
    
    rb->buffer[rb->head] = data;
    rb->head = (rb->head + 1) % rb->capacity;
    rb->count++;
    return 1;
}

uint8_t RingBuffer_ReadByte(RingBuffer_t* rb, uint8_t* data) {
    if (RingBuffer_IsEmpty(rb)) return 0;
    
    *data = rb->buffer[rb->tail];
    rb->tail = (rb->tail + 1) % rb->capacity;
    rb->count--;
    return 1;
}

uint16_t RingBuffer_Write(RingBuffer_t* rb, const uint8_t* data, uint16_t len) {
    uint16_t i;
    for (i = 0; i < len && !RingBuffer_IsFull(rb); i++) {
        RingBuffer_WriteByte(rb, data[i]);
    }
    return i;
}

uint16_t RingBuffer_Read(RingBuffer_t* rb, uint8_t* data, uint16_t len) {
    uint16_t i;
    for (i = 0; i < len && !RingBuffer_IsEmpty(rb); i++) {
        RingBuffer_ReadByte(rb, &data[i]);
    }
    return i;
}

uint8_t RingBuffer_Peek(const RingBuffer_t* rb, uint8_t* data) {
    if (RingBuffer_IsEmpty(rb)) return 0;
    *data = rb->buffer[rb->tail];
    return 1;
}

